package com.xyzwps.mvckotlin.handler

import com.xyzwps.mvckotlin.assertReqParam
import com.xyzwps.mvckotlin.handler.helper.ModelAndView
import com.xyzwps.mvckotlin.handler.helper.render
import com.xyzwps.mvckotlin.isNotEmpty
import com.xyzwps.mvckotlin.service.ArticleService
import kotlinx.coroutines.reactive.awaitFirst
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Component
import org.springframework.util.MultiValueMap

@Component
class ArticleHandler(val articleService: ArticleService) {

    companion object {
        private val log = LoggerFactory.getLogger(ArticleHandler::class.java)
    }

    fun get() = render { req ->
        val id: Long = req.pathVariable("id").toLong()
        log.info("try to get article by id {}", id)
        val article = articleService.getById(id)
        log.info("the article found is {}", article?.title)

        // TODO: 加标记表示是自己

        if (article == null) ModelAndView("article/not-found")
        else ModelAndView("article/reader", mapOf(Pair("article", article)))
    }

    fun newArticlePage() = render { ModelAndView("article/editor") }

    fun changeArticlePage() = render { req ->
        val id: Long = req.pathVariable("id").toLong()
        val article = articleService.getById(id)
        ModelAndView("article/editor", mapOf("article" to article))
    }

    fun save() = render {
        val dto = formDataToArticleDto(it.formData().awaitFirst())
        if (dto.id == null) {
            val newArticle = articleService.addNewArticle(dto.title, dto.content)
            ModelAndView("redirect:/article/id/${newArticle.id}")
        } else {
            // TODO: 只有自己的才可以修改
            articleService.update(dto.id, dto.title, dto.content)
            ModelAndView("redirect:/article/id/${dto.id}")
        }
    }
}

internal data class ArticleDto(val id: Long?, val title: String, val content: String)

internal fun formDataToArticleDto(formData: MultiValueMap<String, String>): ArticleDto {
    val title = formData.getFirst("title")
    val content = formData.getFirst("content")
    val id = formData.getFirst("id")

    assertReqParam(isNotEmpty(title), "不可缺少标题")
    assertReqParam(isNotEmpty(content), "不可缺少内容")

    return ArticleDto(id?.toLong(), title!!, content!!)
}
